package com.hanscan.util.signing;


import com.hanscan.persistence.entities.Event;
import com.hanscan.persistence.entities.EventType;
import com.hanscan.persistence.entities.Terminal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

public class MonthlySigning {
    private List<DailySigning> listDailySigning;
    private long idUser;
    private int month,  year;

    /**
     * Constructor
     * @param long idUser id del usuario
     * @param int month mes de la busqueda
     * @param int year año de la busqueda
     * @param EntityManager entityManager
     */
    public MonthlySigning(long idUser,
                        int month,
                        int year) throws Exception
    {
        this.idUser = idUser;
        this.month = month;
        this.year = year;
        int daysOfMonth = getDaysOfMonth(year, month);

        Calendar beginningDay = Calendar.getInstance();
        beginningDay.set(Calendar.YEAR, year);
        beginningDay.set(Calendar.MONTH, month);
        beginningDay.set(Calendar.DATE, 1);
        beginningDay.set(Calendar.HOUR_OF_DAY, 0);
        beginningDay.set(Calendar.MINUTE, 0);
        Date dateBeginning = beginningDay.getTime();


        Calendar dayEnd = Calendar.getInstance();
        dayEnd.set(Calendar.YEAR, year);
        dayEnd.set(Calendar.MONTH, month);
        dayEnd.set(Calendar.DATE, daysOfMonth);
        dayEnd.set(Calendar.HOUR_OF_DAY, 23);
        dayEnd.set(Calendar.MINUTE, 59);
        dayEnd.set(Calendar.SECOND, 59);
        Date dateEnd = dayEnd.getTime();

      //  List<Event> listMonth =
            //eventFacade.findEventsByUserBetweenDaysByTerminalType(dateBeginning, dateEnd, idUser);
       // this.listDailySigning = searchSigningDay(daysOfMonth, listMonth);
    }

    /**
     * Metodo para saber el numero máximo de días del mes y el año pasados como
     * argumentos
     * @param year año.
     * @param month mes a conocer el numero de días que tiene
     * @return int con el numero de dias del mes
     */
    public int getDaysOfMonth(int year, int month)
    {
        int daysOfMonth;

        // Vamos a crear un GregorianCalendar con el mes y el año pasados por
        // argumento. El día es indiferente, así que ponemos el 1 del mes.
        GregorianCalendar gregorianCalendar =
            new GregorianCalendar(year, month, 1);

        daysOfMonth = gregorianCalendar.getActualMaximum(Calendar.DAY_OF_MONTH);

        return daysOfMonth;
    }


    /**
     * Relleana un fichaje cuando se ha terminado un día, sin fichar a la saida
     * @param calendarError fichaje a introducir
     * @param signingDay lista de fichajes diarios
     * @param finalDay boolean para indicar si el fichaje que se introduce el
     * ultimo del dia o el primero del dia siguiente
     */
    private void completeSigningFailed
        (Calendar calendarError, List<Event> signingDay, boolean finalDay)
    {
        Event signingError = new Event();
        Date date = new Date();
        date.setTime(calendarError.getTimeInMillis());
        signingError.setDateTime(date);
        Terminal terminal = new Terminal();
        terminal.setTerminalId((long) -1);
        signingError.setTerminal(terminal);
        EventType eventType = new EventType();
        eventType.setIdEventType((long) 6);
        signingError.setEventType(eventType);
        signingError.setUser(signingDay.get(signingDay.size()-1).getUser());
//        if(finalDay)
//        {
//            signingError.setEventId(signingDay.
//            get(signingDay.size()-1).getEventId()+1);
//        }
//        else
//        {
//            signingError.setEventId(signingDay.get(0).getEventId() - 1);
//        }
        signingError.setEventId((long) -1);

        signingDay.add(signingError);
    }

    /**
     * Metodo que rellena los fichajes de cada dia
     * @param Maxday total de dias del mes
     * @param listSigning lista de todos los fichajes del mes
     * @return List <DailySigning> devuelve una lista de DailySigning con los
     * fichajes de cada dia.
     */
    private List<DailySigning> searchSigningDay(int daysOfMonth,
                                                List<Event> listSigning)
    {
        int numberSignings = listSigning.size();
        List<DailySigning> monthlySigning = new ArrayList<DailySigning>();
        int error = 0;

        //El mes no tiene fichajes
        if (numberSignings == 0)
        {
            for (int dayMonth = 0; dayMonth < daysOfMonth; dayMonth++)
            {
                DailySigning dailySigning = new DailySigning();
                monthlySigning.add(dailySigning);
            }
        }
        //El mes tiene fichajes
        else
        {

            int posicionList = 0;
            Calendar timeSigning  = Calendar.getInstance();
            timeSigning.setTimeInMillis(listSigning.get(posicionList).
                getDateTime().getTime());

            for (int posicionMouth =0;posicionMouth<daysOfMonth;posicionMouth++)
            {
                if (posicionList < numberSignings)
                {
                    timeSigning.setTimeInMillis(listSigning.get(posicionList).
                        getDateTime().getTime());
                    int daySigning = timeSigning.get(Calendar.DATE);
                    if (posicionMouth == (daySigning - 1))
                    {
                        List<Event> signingDay = new ArrayList<Event>();

                        while (daySigning == (posicionMouth + 1) &&
                            (posicionList < numberSignings))
                        {
                            signingDay.add(listSigning.get(posicionList));
                            posicionList++;
                            if (posicionList < numberSignings)
                            {
                                timeSigning.setTimeInMillis
                                    (listSigning.get(posicionList).getDateTime().
                                    getTime());
                                daySigning = timeSigning.get(Calendar.DATE);
                            }
                        }
                        //comprueba que el nuemero de fichajes es par par
                        //comprobar que no se ha olvidado de fichar alguna vez
                        int size = signingDay.size();
                        size = size % 2;
                        if (size != 0)
                        {
                            //error en el fichaje de salida
//                            if (error == 0)
//                            {
                                error = 1;
                                boolean finalDay = true;
                                Calendar calendarError = Calendar.getInstance();
                                calendarError.setTimeInMillis
                                    (signingDay.get(signingDay.size() - 1).
                                    getDateTime().getTime());
                                calendarError.set(Calendar.HOUR_OF_DAY, 23);
                                calendarError.set(Calendar.MINUTE, 59);
                                completeSigningFailed(calendarError,signingDay,
                                    finalDay);
                                DailySigning signingDiary =
                                    new DailySigning(signingDay, posicionMouth);
                                monthlySigning.add(signingDiary);
//                            }
//                            //arrreglo del dia siguiente
//                            else
//                            {
//                                error = 0;
//                                Calendar calendarError = Calendar.getInstance();
//                                calendarError.setTimeInMillis
//                                    (signingDay.get(signingDay.size() - 1).
//                                    getDateTime().getTime());
//                                calendarError.set(Calendar.AM_PM, 0);
//                                calendarError.set(Calendar.HOUR, 0);
//                                calendarError.set(Calendar.MINUTE, 0);
//                                boolean finalDay = false;
//                                completeSigningFailed(calendarError,signingDay,
//                                    finalDay);
//                                DailySigning signingDiary =
//                                    new DailySigning(signingDay, posicionMouth);
//                                monthlySigning.add(signingDiary);
//
//                            }
                        }
                        else
                        {
                            DailySigning signingDiary =
                                new DailySigning(signingDay, posicionMouth);
                            monthlySigning.add(signingDiary);
                        }
                    }
                    else
                    {
                        DailySigning signingDiary = new DailySigning();
                        monthlySigning.add(signingDiary);
                    }
                }
                else
                {
                    DailySigning signingDiary = new DailySigning();
                    monthlySigning.add(signingDiary);
                }
            }
        }
        return monthlySigning;
    }

    ///////////////////////////////////////////////////////////////////
    ///                     Getters y setters                       ///
    ///////////////////////////////////////////////////////////////////


    /**
     * get del id de usuario
     * @return long
     */
    public long getIdUser()
    {
        return idUser;
    }

    /**
     * set del id de usuario
     * @param long
     */
    public void setIdUser(long idUser)
    {
        this.idUser = idUser;
    }

    /**
     * get de la lista de DailySigning del mes
     * @return List<DailySigning>
     */
    public List<DailySigning> getListDay()
    {
        return listDailySigning;
    }

    /**
     * set de la lista de DailySigning del mes
     * @param listDailySigning List<DailySigning>
     */
    public void setListDay(List<DailySigning> listDay)
    {
        this.listDailySigning = listDay;
    }

    /**
     * get del mes
     * @return int
     */
    public int getMonth()
    {
        return month;
    }

    /**
     * set del mes
     * @param month int
     */
    public void setMonth(int m)
    {
        this.month = m;
    }

    /**
     * get del año
     * @return int
     */
    public int getYear()
    {
        return year;
    }

    /**
     * set del año
     * @param year int
     */
    public void setYear(int y)
    {
        this.year = y;
    }

}
